package DataModel.ConnectivityManager;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

import DataModel.LayoutManager.CRectangle;

public class CRectangleConnectivityGraph 
{
	/***************************************************/
	/****** C'tors *************************************/
	/***************************************************/
	public CRectangleConnectivityGraph(LinkedList<CRectangle> recsList)
	{
		m_recsConections = new Hashtable<Long, LinkedList<Long>>(recsList.size());
		m_sets = new Hashtable<Long, LinkedList<Long>>(recsList.size());
		
		for (CRectangle rec : recsList) 
		{
			LinkedList<Long> list = new LinkedList<Long>();
			
			list.add(rec.getID());			
			m_sets.put(rec.getID(), list);
			m_recsConections.put(rec.getID(), list);
		}
	}
	
	/***************************************************/
	/****** Members ************************************/
	/***************************************************/
	private Hashtable<Long, LinkedList<Long>> m_recsConections;
	private Hashtable<Long, LinkedList<Long>> m_sets;

	
	/***************************************************/
	/****** Getters / Setters **************************/
	/***************************************************/
	public Hashtable<Long, LinkedList<Long>> getRecsConections() {
		return m_recsConections;
	}

	public void setRecsConections(Hashtable<Long, LinkedList<Long>> conections) {
		m_recsConections = conections;
	}
	
	public Hashtable<Long, LinkedList<Long>> getSets() {
		return m_sets;
	}

	public void setSets(Hashtable<Long, LinkedList<Long>> m_sets) {
		this.m_sets = m_sets;
	}

	/***************************************************/
	/****** Public Functions ***************************/
	/***************************************************/
	/**
	 * Merges given connectivity hash with the graph
	 * @param recsTable - hash table, the key is rec ID, the value is recs link list 
	 */
	public void AddToGraph(Hashtable<Long, LinkedList<CRectangle>> recsTable)
	{
		// go over all keys of given hash
		for (Long id : recsTable.keySet()) 
		{
			LinkedList<Long> l = m_recsConections.get(id); 
			// create linked list for new key
			if(m_recsConections.get(id) == null)
				m_recsConections.put(id, new LinkedList<Long>());
			
			// add all given connected recs
			for (CRectangle rec : recsTable.get(id)) 
				m_recsConections.get(id).add(rec.getID());
		}
	}
	
	/**
	 * Run Union-Find algorithm for finding connectivity graph
	 */
	public void RunUnionFind()
	{	
		for (Long ver1 : m_recsConections.keySet()) 
		{			
			for (Long ver2 : m_recsConections.get(ver1))
			{
				if(!AreListsEqual(m_sets.get(ver1),m_sets.get(ver2)))
				{
					for (Long long1 : m_sets.get(ver1)) {
						if(!m_sets.get(ver2).contains(long1))
							m_sets.get(ver2).add(long1);
					}	
				}
			}
		}
		
		LinkedList<Long> c = m_sets.get(0);
	}
	
	/**
	 * Determines weather two rectangles are connected 
	 * @param id1 - First rectangle ID
	 * @param id2 - Second rectangle ID
	 * @return true if rectangles are connected
	 */
	public boolean AreConnected(long id1, long id2)
	{
		if(m_sets.keySet().contains(id1) && m_sets.keySet().contains(id2) && m_sets.get(id1).contains(id2))
			return true;
		
		return false;
	}
	
	private boolean AreListsEqual(LinkedList<Long> list1, LinkedList<Long> list2)
	{
		for (Long long1 : list1) {
			for (Long long2 : list2) {
				if(long1 != long2)
					return false;
			}
		}
		
		return true;
	}
}







